package com.dms.modules.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dms.common.service.impl.BaseServiceImpl;
import com.dms.modules.product.entity.Product;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.dms.common.exception.BusinessException;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.Collections;
import java.util.ArrayList;

/**
 * 商品基础服务实现类
 * @param <M> Mapper类型
 * @param <T> 实体类型
 */
@Slf4j
@Service
public abstract class BaseProductServiceImpl<M extends BaseMapper<T>, T> extends BaseServiceImpl<M, T> {
    
    @Autowired
    protected RedisTemplate<String, Object> redisTemplate;
    
    // 缓存过期时间（小时）
    protected static final long CACHE_EXPIRE_HOURS = 24;
    
    @Override
    protected void buildQueryWrapper(LambdaQueryWrapper<T> wrapper, Map<String, Object> conditions) {
        if (conditions == null) {
            return;
        }
        
        // 基础查询条件构建
        conditions.forEach((key, value) -> {
            if (value != null) {
                try {
                    // 使用反射获取字段名对应的getter方法
                    String fieldName = key;
                    if (key.contains("_")) {
                        // 将下划线命名转换为驼峰命名
                        fieldName = convertToCamelCase(key);
                    }
                    // 获取字段对应的Function
                    SFunction<T, ?> function = getFieldFunction(fieldName);
                    if (function != null) {
                        wrapper.eq(function, value);
                    }
                } catch (Exception e) {
                    log.warn("Failed to build query condition for field: {}", key, e);
                }
            }
        });
    }
    
    /**
     * 将下划线命名转换为驼峰命名
     */
    private String convertToCamelCase(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        
        StringBuilder result = new StringBuilder();
        boolean capitalizeNext = false;
        
        for (int i = 0; i < str.length(); i++) {
            char currentChar = str.charAt(i);
            if (currentChar == '_') {
                capitalizeNext = true;
            } else {
                if (capitalizeNext) {
                    result.append(Character.toUpperCase(currentChar));
                    capitalizeNext = false;
                } else {
                    result.append(currentChar);
                }
            }
        }
        
        return result.toString();
    }

    /**
     * 获取字段对应的Function
     * @param fieldName 字段名
     * @return 字段对应的Function
     */
    protected abstract <R> SFunction<T, R> getFieldFunction(String fieldName);

    /**
     * 更新实体状态
     * @param id 实体ID
     * @param statusField 状态字段
     * @param value 状态值
     * @return 是否成功
     */
    protected boolean updateStatus(Long id, SFunction<T, Integer> statusField, Integer value) {
        T entity = getById(id);
        if (entity == null) {
            throw new BusinessException("实体不存在");
        }
        return lambdaUpdate()
                .set(statusField, value)
                .eq(getIdField(), id)
                .update();
    }

    /**
     * 获取ID字段
     * @return ID字段的Function
     */
    protected abstract SFunction<T, Long> getIdField();

    /**
     * 检查实体是否存在
     * @param id 实体ID
     * @return 是否存在
     */
    protected boolean exists(Long id) {
        return getById(id) != null;
    }

    /**
     * 检查实体是否存在，不存在则抛出异常
     * @param id 实体ID
     * @param errorMessage 错误信息
     */
    protected void checkExists(Long id, String errorMessage) {
        if (!exists(id)) {
            throw new BusinessException(errorMessage);
        }
    }
    
    /**
     * 分页查询
     * @param page 分页参数
     * @param conditions 查询条件
     * @return 分页结果
     */
    protected IPage<T> page(Page<T> page, Map<String, Object> conditions) {
        LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>();
        buildQueryWrapper(wrapper, conditions);
        return page(page, wrapper);
    }
    
    /**
     * 从缓存获取实体
     * @param id 实体ID
     * @param cacheKey 缓存键
     * @return 实体
     */
    protected T getFromCache(Long id, String cacheKey) {
        String key = cacheKey + id;
        T entity = (T) redisTemplate.opsForValue().get(key);
        if (entity == null) {
            entity = getById(id);
            if (entity != null) {
                redisTemplate.opsForValue().set(key, entity, CACHE_EXPIRE_HOURS, TimeUnit.HOURS);
            }
        }
        return entity;
    }
    
    /**
     * 更新缓存
     * @param id 实体ID
     * @param entity 实体
     * @param cacheKey 缓存键
     */
    protected void updateCache(Long id, T entity, String cacheKey) {
        String key = cacheKey + id;
        redisTemplate.opsForValue().set(key, entity, CACHE_EXPIRE_HOURS, TimeUnit.HOURS);
    }
    
    /**
     * 删除缓存
     * @param id 实体ID
     * @param cacheKey 缓存键
     */
    protected void deleteCache(Long id, String cacheKey) {
        String key = cacheKey + id;
        redisTemplate.delete(key);
    }
    
    /**
     * 批量获取实体
     * @param ids 实体ID列表
     * @param cacheKey 缓存键
     * @return 实体列表
     */
    protected List<T> listByIds(List<Long> ids, String cacheKey) {
        if (ids == null || ids.isEmpty()) {
            return Collections.emptyList();
        }
        
        List<T> result = new ArrayList<>();
        List<Long> uncachedIds = new ArrayList<>();
        
        // 从缓存获取
        for (Long id : ids) {
            T entity = getFromCache(id, cacheKey);
            if (entity != null) {
                result.add(entity);
            } else {
                uncachedIds.add(id);
            }
        }
        
        // 从数据库获取未缓存的实体
        if (!uncachedIds.isEmpty()) {
            List<T> uncachedEntities = listByIds(uncachedIds);
            for (T entity : uncachedEntities) {
                result.add(entity);
                updateCache(getIdField().apply(entity), entity, cacheKey);
            }
        }
        
        return result;
    }
} 